/*
 * 文件名：SystemUtils.java
 * 版权：Copyright 2013-2013 Hugedata Tech. Co. Ltd. All Rights Reserved
 * 描述：〈描述〉
 * 修改人：〈修改人〉
 * 修改时间：YYYY-MM-DD
 * 跟踪单号：〈跟踪单号〉
 * 修改单号：〈修改单号〉
 * 修改内容：〈修改内容〉
 */
package com.hugedata.cdnserver.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.rmi.RemoteException;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.log4j.Logger;
import org.apache.zookeeper.common.IOUtils;

import com.hugedata.cdn.util.GlobalConstantDef;

/**
 * 
 * @ClassName: SystemUtils
 * @Description: 系统操作工具类
 * @author LuXiuMin
 * @date 2013-8-13 上午9:10:20
 * 
 */
public final class SystemUtils
{
    private final static Logger LOGGER = Logger.getLogger(SystemUtils.class);
    private static Logger ossLogger = Logger.getLogger(SystemUtils.class);
    private static Properties props = null;
    private final static String ROW_DELIMITER = System
            .getProperty("line.separator");
    private final static String OS_ENCODEING = System
            .getProperty("file.encoding");

    /**
     * constructor
     */
    private SystemUtils()
    {

    }

    /**
     * 判断字符串是否为空
     * 
     * @param str
     *            input param
     * @return boolean
     */
    public static boolean isEmpty(String str)
    {
        return (null == str) || "".equals(str);
    }

    /**
     * 判断字符串不为空
     * 
     * @param str
     *            input param
     * @return boolean
     */
    public static boolean isNotEmpty(String str)
    {
        return !isEmpty(str);
    }

    public static int getSeedsFileLineNumbers(String configFilePath)
    {
        int count = 0;
        String seedTopFileName = SystemUtils.getCfg(configFilePath)
                .getProperty("top100_file_name");
        // BufferedReader b = new BufferedReader(new InputStreamReader(
        // ClassLoader.getSystemResourceAsStream(SystemUtils.class
        // .getResource("/").getFile() + seedTopFileName)));

        String value;
        BufferedReader b = null;
        try
        {
            b = new BufferedReader(new FileReader(SystemUtils.class
                    .getResource("/").getPath() + seedTopFileName));
            value = b.readLine();
            while (value != null)
            {
                count++;
                value = b.readLine();
            }
        }
        catch (FileNotFoundException e)
        {
            LOGGER.error("读取Top文件失败,文件未找到" + e);
        }
        catch (IOException e)
        {
            LOGGER.error("文件读写错误," + e);
        }
        finally
        {
            if (b != null)
            {

                try
                {
                    b.close();
                }
                catch (IOException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        LOGGER.info("Top文件行数 " + count);
        return count;
    }

    public static String getProp(String keyName)
    {
        return getCfg(GlobalConstantDef.CONFIG_PATH).getProperty(keyName);
    }
    
    public synchronized static Properties getCfg(String configFilePath)
    {
        if (props == null)
        {
            props = new Properties();
        }

        InputStream in;
        ClassLoader cl = SystemUtils.class.getClassLoader();
        if (cl != null)
        {
            in = cl.getResourceAsStream(configFilePath);
        }
        else
        {
            in = ClassLoader.getSystemResourceAsStream(configFilePath);
        }

        if (in == null)
        {
            File file = new File(configFilePath);
            try
            {
                in = new BufferedInputStream(new FileInputStream(file));
            }
            catch (FileNotFoundException e)
            {
                LOGGER.info("没有找到配置文件" + configFilePath, e);
            }
            if (in == null)
            {
                LOGGER.info("加载配置文件" + configFilePath + "失败");
            }
        }

        try
        {
            props.load(in);
            if (in != null)
            {
                in.close();
            }
        }
        catch (Exception e)
        {
            LOGGER.error("加载配置文件" + configFilePath + "失败: " + e);
        }
        return props;
    }

    public static String getYesterDate()
    {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, -1);
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
        String nowDate = f.format(c.getTime());

        LOGGER.info("getYesterDate " + nowDate);
        return nowDate;
    }

    public static String get24HHString()
    {
        Calendar c = Calendar.getInstance();
        Date date = new Date();
        c.setTime(date);
        SimpleDateFormat f = new SimpleDateFormat("HH");
        String hh = f.format(c.getTime());
        return hh;
    }

    public static String getCurentDate()
    {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 0);
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
        String nowDate = f.format(c.getTime());

        LOGGER.info("getCurentDate " + nowDate);
        return nowDate;
    }

    public static boolean isFirstDayOfMonth(String dateString)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try
        {
            date = sdf.parse(dateString);
        }
        catch (ParseException e)
        {
            LOGGER.error("Date parse error " + e);
            return false;
        }
        // 得到本月1号
        Calendar cal = Calendar.getInstance();
        cal.setLenient(true);
        cal.setTime(date);
        int dayOfMonth = cal.get(Calendar.DATE);
        if (dayOfMonth == 1)
        {
            return true;
        }
        return false;
    }

    public static String getbeforeYesterday(String dateString)
    {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try
        {
            date = sdf.parse(dateString);
        }
        catch (ParseException e)
        {
            LOGGER.error("Date parse error" + e);
            return "";
        }
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, -1);
        String beforeYesterday = sdf.format(c.getTime());

        LOGGER.info("getbeforeYesterday " + beforeYesterday);
        return beforeYesterday;
    }

    // 根据传入的值获取前后的时间
    public static String getDateBefore(int time)
    {
        Format f = new SimpleDateFormat("yyyyMMdd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, time);
        return f.format(c.getTime());

    }

    // 获取当前月份前一个月的最后一天
    public static String getLastMonthEndDay()
    {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date strDateTo = calendar.getTime();
        return df.format(strDateTo);

    }

    public static String getDate(final String dataStr)
    {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try
        {
            date = sdf.parse(dataStr);
        }
        catch (ParseException e)
        {
            LOGGER.error("getDate Parse date Exception " + e);
        }
        c.setTime(date);
        String dateStr = sdf.format(c.getTime());
        return dateStr;
    }

    public static String getTaskEndDate(final Date dataStr)
    {
        String HH23mm59ss59 = "235959";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String formatDate = sdf.format(dataStr) + HH23mm59ss59;
        return formatDate;
    }

    public static String getTaskEndDateOfCrawleTool()
    {
        String endDate = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String formatDate = sdf.format(new Date());

        Calendar calendar = new GregorianCalendar();
        int actualMaximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        endDate = formatDate + actualMaximum + "235959";
        return endDate;
    }

    public static String getTaskBeginTime(final String cfgBeginDate)
    {
        String beginDate = "";
        Date nowDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

        try
        {
            Date sdfDate = sdf.parse(cfgBeginDate);
            boolean flag = sdfDate.before(nowDate);
            // 配置的开始时间早于系统当前时间,使用系统时间
            if (flag == true)
            {
                beginDate = sdf.format(nowDate);
                LOGGER.info("配置的开始时间早于系统当前时间,使用系统时间 " + beginDate);
            }// 配置的开始时间晚于系统当前时间,使用配置时间
            else
            {
                beginDate = sdf.format(sdfDate);
                LOGGER.info("配置的开始时间晚于系统当前时间,使用配置时间 " + beginDate);
            }
        }
        catch (ParseException e)
        {
            LOGGER.error("Date parse error " + e);
        }
        return beginDate;
    }

    /*
     * public static int getDnsDelayAndQosToolRunNum(final String beginDate) {
     * int runingNumer = 0; // qos,dnsdelay工具运行次数偏移量(只能是正负整数) String
     * qosDnsDelayOffset = SystemUtils.getCfg(GlobalConstantDef.CONFIG_PATH)
     * .getProperty("qos_dnsdelay_offset").trim(); int qosDnsDelayOffsetInt =
     * Integer.valueOf(qosDnsDelayOffset); SimpleDateFormat sdf = new
     * SimpleDateFormat("yyyyMMddHHmmss"); try { Date beginDateFmt =
     * sdf.parse(beginDate); Calendar c = Calendar.getInstance();
     * c.setTime(beginDateFmt); int hourse = c.get(Calendar.HOUR_OF_DAY);
     * runingNumer = 24 - hourse + qosDnsDelayOffsetInt; } catch (ParseException
     * e) { LOGGER.error("getDnsDelayAndQosToolRunInterval Date parse error " +
     * e); } return runingNumer; }
     */

    /**
     * 判断文件的编码格式
     * 
     * @param fileName
     * @return 文件编码格式
     * @throws Exception
     */
    public static String getFileEncode(final String fileName)
    {
        String code = null;
        try
        {
            // BufferedReader bin = new BufferedReader(new InputStreamReader(
            // ClassLoader.getSystemResourceAsStream(fileName)));
            BufferedReader bin = new BufferedReader(new FileReader(
                    SystemUtils.class.getResource("/").getPath() + fileName));
            int p = (bin.read() << 8) + bin.read();
            switch (p)
            {
            case 0xefbb:
                code = "UTF-8";
                break;
            case 0xfffe:
                code = "Unicode";
                break;
            case 0xfeff:
                code = "UTF-16BE";
                break;
            default:
                code = "GBK";
            }
        }
        catch (Exception e)
        {
            LOGGER.info("parse top file encode error " + e);
        }
        return code;
    }

    public static String assemblingString(final String str, final String dateStr)
    {
        String tempStr = str;
        String tempDate = dateStr;
        String resultStr = tempStr.substring(0, tempStr.lastIndexOf('/')) + "/"
                + tempDate + tempStr.substring(tempStr.lastIndexOf('/'));
        return resultStr;
    }

    public static String getCurrentYearMonth()
    {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String yearMonth = sdf.format(date);
        return yearMonth;
    }

    public static boolean uploadToHdfsFromLocDir(Configuration config,
            String local, String hdfs)
    {
        FileSystem hdfsFileSys = null;
        FileSystem localFileSys = null;
        FSDataOutputStream out = null;
        FSDataInputStream in = null;
        try
        {
            // 获得hdfs文件系统设置
            hdfsFileSys = FileSystem.newInstance(config);
            // 获得本地文件系统设置
            localFileSys = FileSystem.newInstanceLocal(config);

            // 本地输入目录
            Path inputDir = new Path(local);
            // 远程输出文件
            Path hdfsFile = new Path(hdfs);
            // 数组,用来循环保存本地文件目录信息
            FileStatus[] inputFiles = localFileSys.listStatus(inputDir);
            // 创建输出hdfs文件
            out = hdfsFileSys.create(hdfsFile);
            // 循环取出本地文件目录信息
            for (int i = 0; i < inputFiles.length; i++)
            {
                // 打开本地文件
                in = localFileSys.open(inputFiles[i].getPath());

                byte[] ioBuffer = new byte[1024];

                // 按行读取
                int readLen = in.read(ioBuffer);
                while (-1 != readLen)
                {
                    out.write(ioBuffer, 0, readLen);
                    readLen = in.read(ioBuffer);
                }
            }
            
            out.flush();
            LOGGER.info(local + "文件上传Hdfs系统成功 ");
            return true;
        }
        catch (IOException e)
        {
            LOGGER.error(local + "文件上传Hdfs系统出错了 ", e);
            return false;
        }
        finally
        {
            IOUtils.closeStream(in);
            IOUtils.closeStream(out);
            IOUtils.closeStream(localFileSys);
            IOUtils.closeStream(hdfsFileSys);
        }
    }

    private static boolean writeTxtFile(String content, File fileName)
            throws Exception
    {
        RandomAccessFile mm = null;
        boolean flag = false;
        FileOutputStream o = null;
        try
        {
            o = new FileOutputStream(fileName);
            String newContentStr = content.trim();
            o.write(newContentStr.getBytes(OS_ENCODEING));
            flag = true;
        }
        catch (Exception e)
        {
            LOGGER.info("输出" + fileName + "文件到本地失败,", e);
        }
        finally
        {
            IOUtils.closeStream(o);
            if (mm != null)
            {
                mm.close();
            }
        }
        return flag;
    }

//    private static String getDomain(String url)
//    {
//        String host;
//        URI uri = null;
//        try
//        {
//            uri = new URI(url);
//        }
//        catch (URISyntaxException e)
//        {
//            e.printStackTrace();
//        }
//        host = uri.getHost() + " ";
//
//        String[] BeReplacedStrs = new String[]
//        { ".com.cn", ".edu.cn", ".net.cn", ".org.cn", ".co.jp", ".gov.cn",
//                ".co.uk", "ac.cn", ".edu", ".tv", ".info", ".com", ".ac",
//                ".ag", ".am", ".at", ".be", ".biz", ".bz", ".cc", ".cn",
//                ".com", ".de", ".es", ".eu", ".fm", ".gs", ".hk", ".in",
//                ".info", ".io", ".it", ".jp", ".la", ".md", ".ms", ".name",
//                ".net", ".nl", ".nu", ".org", ".pl", ".ru", ".sc", ".se",
//                ".sg", ".sh", ".tc", ".tk", ".tv", ".tw", ".us", ".co", ".uk",
//                ".vc", ".vg", ".ws", ".il", ".li", ".nz" };
//
//        for (String oneBeReplacedStr : BeReplacedStrs)
//        {
//            String BeReplacedStr = oneBeReplacedStr + " ";
//            if (host.indexOf(BeReplacedStr) != -1)
//            {
//                host = host.replace(BeReplacedStr, "");
//                break;
//            }
//        }
//
//        int dotIndex = host.lastIndexOf(".");
//        host = uri.getHost().substring(dotIndex + 1);
//        return host;
//    }

    public static String getThirdDayBefore(int dayInt)
    {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, dayInt);
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
        String nowDate = f.format(c.getTime());

        // LOGGER.info("getThirdDayBefore " + nowDate);
        return nowDate;
    }

    public static void deleteMiddleData(String hdfsInputPath, Configuration conf)
    {
        String delete_middle_date_day = SystemUtils
                .getCfg(GlobalConstantDef.CONFIG_PATH)
                .get("delete_middle_date_day").toString().trim();
        int dayInt = Integer.valueOf(delete_middle_date_day).intValue();

        for (int i = 0; i < Math.abs(dayInt); i++)
        {
            String thirdDayBefore = SystemUtils.getThirdDayBefore(dayInt
                    + dayInt + i);
            String assemblingString = SystemUtils.assemblingStringByDate(
                    hdfsInputPath, thirdDayBefore);
            HDFSUtilsCDN.delete(assemblingString, conf);
        }
    }

    public static String assemblingStringByDate(final String str,
            final String dateStr)
    {
        String tempStr = str;
        String[] splitArr = tempStr.split("/");
        String resultStr = "/" + splitArr[1] + "/" + dateStr + "/"
                + splitArr[3];
        return resultStr;
    }

    public static void main(String[] args) throws InterruptedException
    {
        String icp1 = ".abc".replaceAll("\\.", "");
        Configuration conf = new Configuration();
        SystemUtils.deleteMiddleData("/cdn/20140418/domainReverse", conf);

        List<Seed> list = new ArrayList<Seed>();
        Seed seed = new Seed();
        seed.setIcp(".qqbaobao");
        seed.setLink("http://www.qqbaobao.com");
        Seed seed2 = new Seed();
        seed2.setIcp(".qq");
        seed2.setLink("http://www.qq.com");

        Seed seed3 = new Seed();
        seed3.setIcp(".qq163");
        seed3.setLink("http://www.qq163.com");

        Seed seed4 = new Seed();
        seed4.setIcp(".qiyou");
        seed4.setLink("http://www.qiyou.com");

        list.add(seed);
        list.add(seed2);
        list.add(seed4);
        list.add(seed3);
        Collections.sort(list, new CompareUtil());

        System.out.println(list);

        /*
         * SystemUtils.loadTopFile("http://192.168.72.149/SiteWebService.asmx",
         * SystemUtils.cfg, "");
         */
        /*
         * Double valueOf = Double.valueOf("-1"); // http://www.qianyan001.com
         * String string2 = "http://www.qianyan001.com"; int firstPointIdx =
         * string2.indexOf("."); int secondPointIdx = string2.indexOf(".",
         * firstPointIdx + 1); String sss = string2.substring(firstPointIdx,
         * secondPointIdx); // System.out.println(sss); String resultStr =
         * "/cdn/20140402/CrawlerDnsCombinationIpInclude"; String
         * delete_middle_date_day = SystemUtils
         * .getCfg(GlobalConstantDef.CONFIG_PATH)
         * .get("delete_middle_date_day").toString().trim(); int dayInt =
         * Integer.valueOf(delete_middle_date_day).intValue(); for (int i = 0; i
         * < Math.abs(dayInt); i++) { String thirdDayBefore =
         * SystemUtils.getThirdDayBefore(dayInt + i + dayInt); String
         * assemblingString = SystemUtils.assemblingStringByDate( resultStr,
         * thirdDayBefore); System.out.println(assemblingString); }
         */
        /*
         * SystemUtils.getSeedsFileLineNumbers(""); int seedsFileLine = 500; //
         * 拆分的小文件行数--12 int splitFileLine = seedsFileLine / 39; // 拆分的小文件个数--41
         * int fileNum = seedsFileLine / splitFileLine; System.out.println();
         */

        /*
         * String yestDate = SystemUtils.getYesterDate(); String yearMonth =
         * yestDate.substring(0, 6); String property =
         * SystemUtils.getCfg().getProperty( "cdn_total_comparison_input_path");
         * System.out.println(get24HHString());
         */
        // String urlString = "http://192.168.10.159:8088/SiteWebService.asmx";
        // loadTopFile(urlString, "./seedtop333.txt", 500);
        /*
         * getSeedsFileLineNumbers("cfg/config.properties"); Configuration conf
         * = new Configuration(); Properties cfg =
         * SystemUtils.getCfg(GlobalConstantDef.CONFIG_PATH);
         * conf.set("mapred.job.tracker", cfg.getProperty("mapred.job.tracker")
         * .trim()); conf.set("fs.default.name",
         * cfg.getProperty("fs.default.name").trim());
         */

        /*
         * outputChineseIcpFile(urlString, "/cdn/config/ChineseIcp.txt",
         * "./ChineseIcp.txt", 500, conf);
         */

        // loadIcpClassfyFile(urlString, "./IcpClassfyFile.txt", 500);
    }
}